|
1
|
|
|
import React, { Component } from "react"; |
|
2
|
|
|
import "../scss/components/Toast.scss"; |
|
3
|
|
|
|
|
4
|
|
|
class Toast extends Component { |
|
5
|
|
|
state = { |
|
6
|
|
|
visible: false, |
|
7
|
|
|
type: "primary", |
|
8
|
|
|
message: "", |
|
9
|
|
|
transitionDirection: "right", |
|
10
|
|
|
position: "top-right", |
|
11
|
|
|
timeout: 5000 |
|
12
|
|
|
} |
|
13
|
|
|
toastTimeout = null; |
|
14
|
|
|
throwToast = (message, type, options) => { |
|
15
|
|
|
const { transitionDirection, position, timeout } = options; |
|
16
|
|
|
const validPositions = ["top-right", "top-left", "top-center", "bottom-right", "bottom-left", "bottom-center"]; |
|
17
|
|
|
const validTypes = ["warn", "success", "error", "info", "primary"]; |
|
18
|
|
|
this.setState({ message, type: [...validTypes].includes(type) ? type : "primary", transitionDirection, position: [...validPositions].includes(position) ? position || "top-right" : "top-right", timeout: timeout || 5000 }, () => { |
|
19
|
|
|
setTimeout(() => { |
|
20
|
|
|
this.setState({ visible: true }, () => { |
|
21
|
|
|
this.toastTimeout = setTimeout(() => { |
|
22
|
|
|
if (this.state.visible) { |
|
23
|
|
|
this.setState({ visible: false }); |
|
24
|
|
|
} |
|
25
|
|
|
}, this.state.timeout); |
|
26
|
|
|
}); |
|
27
|
|
|
}, 250); |
|
28
|
|
|
}); |
|
29
|
|
|
} |
|
30
|
|
|
toast = (message, type, options = {}) => { |
|
31
|
|
|
if (this.state.visible) { |
|
32
|
|
|
clearTimeout(this.toastTimeout); |
|
33
|
|
|
this.setState({ visible: false }, () => { |
|
34
|
|
|
setTimeout(() => { |
|
35
|
|
|
this.throwToast(message, type, options); |
|
36
|
|
|
}, 250); |
|
37
|
|
|
}); |
|
38
|
|
|
} else { |
|
39
|
|
|
this.throwToast(message, type, options); |
|
40
|
|
|
} |
|
41
|
|
|
} |
|
42
|
|
|
closeToast = () => { |
|
43
|
|
|
clearTimeout(this.toastTimeout); |
|
44
|
|
|
this.setState({ visible: false }); |
|
45
|
|
|
} |
|
46
|
|
|
determineShiftDirection = (position, transitionDirection) => { |
|
47
|
|
|
const directions = position.split("-"); |
|
48
|
|
|
if (directions.includes("center")) { |
|
49
|
|
|
return directions[0]; |
|
50
|
|
|
} else { |
|
51
|
|
|
if (directions.includes(transitionDirection)) { |
|
52
|
|
|
return transitionDirection; |
|
53
|
|
|
} else { |
|
54
|
|
|
return directions[1]; |
|
55
|
|
|
} |
|
56
|
|
|
} |
|
57
|
|
|
} |
|
58
|
|
|
renderToast = (message, visible, type) => { |
|
59
|
|
|
const { transitionDirection, position } = this.state; |
|
60
|
|
|
const shiftDirection = this.determineShiftDirection(position, transitionDirection); |
|
61
|
|
|
return <div onClick={this.closeToast} className={`${"toast"} ${visible ? "show" : "hide"}-${shiftDirection} ${type} ${position}`}>{message}</div> |
|
62
|
|
|
} |
|
63
|
|
|
render() { |
|
64
|
|
|
const { message, visible, type } = this.state; |
|
65
|
|
|
return (<>{this.renderToast(message, visible, type)}</>); |
|
66
|
|
|
} |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
export default Toast; |